package com.guqj.nio.netty.pstack.server;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

import java.net.InetSocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.guqj.nio.netty.pstack.pojo.Header;
import com.guqj.nio.netty.pstack.pojo.MessageType;
import com.guqj.nio.netty.pstack.pojo.NettyMessage;

/**
 * 握手认证-服务端
 * 
 * @author guqj
 * @date 2016年11月25日
 */
public class LoginAuthRespHandler extends ChannelHandlerAdapter {

	private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<String, Boolean>();
	private String[] whiteList = new String[] { "localhost" };

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		nodeCheck.remove(ctx.channel().remoteAddress().toString()); // 删除缓存
		ctx.fireExceptionCaught(cause);
	}

	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		NettyMessage message = (NettyMessage) msg;

		// 如果是握手请求，处理，其他透传
		if (message.getHeader() != null && message.getHeader().getType() == MessageType.LOGIN_REQ.value()) {
			System.out.println("Receive Login Auth message: " + message);
			String nodeIndex = ctx.channel().remoteAddress().toString();
			NettyMessage resp = null;
			// 重复登录，拒绝
			if (nodeCheck.containsKey(nodeIndex)) {
				resp = buildResp((byte) -1);
			} else {
				// 白名单
				InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
				String ip = address.getAddress().getHostAddress();
				boolean ok = false;
				for (String whiteIp : whiteList) {
					if (whiteIp.equals(ip)) {
						ok = true;
						break;
					}
				}
				// 认证响应
				resp = ok ? buildResp((byte) 0) : buildResp((byte) -1);
				if (ok) {
					nodeCheck.put(nodeIndex, Boolean.TRUE);
				}
				System.out.println("The login response is " + resp + " and body is " + resp.getBody());
				ctx.writeAndFlush(resp);
			}
		} else {// 往下传
			ctx.fireChannelRead(msg);
		}
	}

	private NettyMessage buildResp(Object body) {
		NettyMessage msg = new NettyMessage();
		Header header = new Header();
		header.setType(MessageType.LOGIN_RESP.value());
		msg.setBody(body);
		return msg;
	}
}
